
// Object.keys
// Object.getOwnPropertyNames

// var obj = {
//   a: 1,
//   b: 2,
//   c: 3
// }

// Object.defineProperty(obj, 'b', {
//   enumerable: false
// })

// console.log(Object.keys(obj)); // ["a", "c"]
// console.log(Object.getOwnPropertyNames(obj)); // ["a", "b", "c"]

// var anObj = { 100: 'a', 2: 'b', 7: 'c' };
// console.log(Object.keys(anObj)); // ['2', '7', '100']
// console.log(Object.getOwnPropertyNames(anObj)); // ['2', '7', '100']

// function ParentClass() {}
// ParentClass.prototype.inheritedMethod = function() {};

// function ChildClass() {
//   this.prop = 5;
//   this.method = function() {};
// }

// ChildClass.prototype = new ParentClass;
// ChildClass.prototype.prototypeMethod = function() {};

// console.log(Object.keys(new ChildClass())); // ["prop", "method"]
// console.log(Object.getOwnPropertyNames(new ChildClass())); // ["prop", "method"]


var newObj = Object.create({}, {
  getVal: {
    value: function () {
      return this.a;
    },
    // enumerable: true
  }
})

newObj.a = 1;
// console.log(newObj.a); // 1
console.log(Object.keys(newObj)); // ["a"]
console.log(Object.getOwnPropertyNames(newObj)); // ["getVal", "a"]

// var arr = ['a', 'b', 'c'];
// console.log(Object.keys(arr)); // ['0', '1', '2']
// console.log(Object.getOwnPropertyNames(arr)); // ["0", "1", "2", "length"]

/**
 * Object.keys()
 * 
 * 返回一个由一个给定对象的自身 可枚举属性!!! 组成的数组
 * 数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致
 * 
 * 
 * Object.getOwnPropertyNames()
 * 
 * 返回一个由指定对象的所有自身属性的属性名
 * （包括不可枚举属性但不包括Symbol值作为名称的属性）组成的数组
 * 枚举属性的顺序与通过 for...in 循环（或 Object.keys）迭代该对象属性时一致
 * 
 * 会忽略描述符
 * 
 * 
 * 共同：
 * 不会获取到原型链上的属性
 * 
 * ES5中 传的参数不是对象（而是一个原始值），会抛出 TypeError
 * ES2015中，非对象的参数将被强制转换为一个对象。
 * 
 */

// 实现 只获取不可枚举的属性 方法

Object.reverseGetOwnPropertyNames = function (obj) {
  const target = obj,
      _keys = Object.keys(target);
      _allKeys = Object.getOwnPropertyNames(target),
      _noenumKeys = [];

  _noenumKeys = _allKeys.filter(keys => {
    const _isInEnum = _keys.indexOf(keys);
    if(_isInEnum === -1)
      return true;
    else
      return false;
  })

  return _noenumKeys;
}

console.log(Object.reverseGetOwnPropertyNames(newObj)); // ["getVal"]
